iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
自我挑戰組

透過Roblox Studio學習Lua語言與基本程式邏輯系列 第 5

Day 5: 迴圈與各類數學函式

  • 分享至 

  • xImage
  •  

好好把今天這篇看完,最後會有驚喜喔~


1. 迴圈

迴圈這項概念是能夠讓你做重複的事情,而不用重複寫同樣的函式,舉個例子:

local number = 0
--我想要每一次把number的值加一,並且把他的值輸出,總共做五次
number += 1
print(number)
number += 1
print(number)
number += 1
print(number)
number += 1
print(number)
number += 1
print(number)
--天啊重複的結構好多

沒錯,重複的結構太多了,這時你一定會想到 啊! 可以用第二天教過的函式來簡化!!

local number = 0
--把它變成函式應該會比較簡單吧!
function OutputValue()
    number += 1
    print(number)
end
--接下來只要重複寫五次函式就好了!
OutputValue()
OutputValue()
OutputValue()
OutputValue()
OutputValue()
--痾重複結構好像還是有點多

那既然我們要重複執行一樣的指令,那為什麼不使用一個可以重複執行指定函式的重複結構呢?
而這項重複結構,就是我們接下來要看的for迴圈

for迴圈

在Lua語言中,for迴圈的寫法像這樣:

for i=0, 5, 1 do
    --做一些事
end

可以看到,在for這項迴圈的第一項變數,我們定義了一個變數i (這邊沒有local也沒關係),這項變數i就是迴圈的初始值,而後面的51分別為條件式更新值

而什麼是初始值、條件式、更新值呢? 在看這些好難懂好難懂的名詞之前,我們先來了解迴圈的原理,所謂的迴圈,我會初步將他分成兩種,分別是有次數限制的迴圈以及無限制的迴圈有次數限制的迴圈意思是在達到或超過指定次數時,跳出迴圈,否則繼續執行迴圈內的指令無限制的迴圈則是I don't give a 法克反正你叫我停就停,而上述的for迴圈就是一種有次數限制的迴圈,那for迴圈的限制次數就是條件式的值

還是很難懂對吧,我們來設想一個情境,今天你媽叫你去樓下買五顆番茄,你買了一顆,然後就直接走回家了,你媽肯定會叫你再下去買,你再買了一顆,然後又直接走回家,你媽叫你再買一顆...... 這樣不斷的循環,直到你總共買了五顆的番茄,你媽才會停止叫你去樓下買番茄,對我知道正常不會有人這麼白目,但如果我們把上面這個情境裡的名詞稍微的調換一下,你就可以了解迴圈的運作模式了,在上述的情境中,初始值就是你身上有的番茄數量,因為一開始你根本沒買,所以初始值就會是0;然後條件式就是你媽要你買五顆番茄,你如果買了0、1、2、3、4顆都不行,你媽會叫你再下去買,除非你買了5顆,你媽才會停止叫你去樓下,最後的更新值就是你每一次購買的番茄數量,因為你很白目所以你每一次都只買一顆,所以更新值就會是1。

我們來把上面的情境寫成程式,會像這樣:

--欸對了其實這三個數值可以先定義好
local TomatoInMyBag = 0 --初始值 (你現在袋子裡的番茄數量)
local TomatoMomNeed = 5 --條件式 (你媽要你買幾顆番茄)
local TomatoEachTimeIBuy = 1 --更新值 (你每一次買幾顆番茄)

for i = TomatoInMyBag, TomatoMomNeed, TomatoEachTimeIBuy do
    --你媽會叫你再下去買番茄,因為在這裡你還沒買5顆
end
--你歷經一波三折終於買了五顆番茄了

也就是說,迴圈內的情境就是你買了0、1、2、3、4顆番茄,迴圈外就是你買了5顆番茄

那再回到最一開始的例子,我想要在每次把number數值加一後輸出他的數值,可以這樣寫:

local number = 0
for i = 0, 5, 1 do
    number += 1
    print(number)
end
--所以輸出就會像:
--0
--1
--2
--3
--4
--5

既然你的初始值是一個已經定義的變數,那為何不把它拿來用呢?

--我們再用一次買番茄的例子
local TomatoInMyBag = 0 --初始值 (你現在袋子裡的番茄數量)
local TomatoMomNeed = 5 --條件式 (你媽要你買幾顆番茄)
local TomatoEachTimeIBuy = 1 --更新值 (你每一次買幾顆番茄)

for i = TomatoInMyBag, TomatoMomNeed, TomatoEachTimeIBuy do
   print("媽我剛剛買了這些番茄: ")
   print(i) 
   --因為i = 你現在袋子裡的番茄數量,所以每一次迴圈經過這邊,i的值都會改變 (因為你白目一次只買一顆)
end
print("好啦五顆番茄")

好啦我們不要這麼白目,一次買兩顆

local TomatoInMyBag = 0
local TomatoMomNeed = 5
local TomatoEachTimeIBuy = 2 --好啦我一次買兩顆

for j = TomatoInMyBag, TomatoMomNeed, TomatoEachTimeIBuy do
   --其實不用i也可以,但因為i的意思是index,所以大家都習慣用i這個字母
   print("媽我剛剛買了這些番茄: ")
   print(j) 
end
print("好啦五顆番茄")
--現在的輸出會變成
--媽我剛剛買了這些番茄: 0
--媽我剛剛買了這些番茄: 2
--媽我剛剛買了這些番茄: 4
--好啦五顆番茄

所以現在,你不僅減少了你下樓的次數,你還多買了一顆 (自己吃掉)

while迴圈

while迴圈就是無限制的迴圈,你唯二讓這個迴圈結束的辦法就是讓所給予的條件符合或用break這個指令 (在下一個章節會提到各項迴圈的特殊指令),在Lua語言裡,while迴圈的寫法像是這樣

while 條件 do
    --條件還沒符合
end
--條件符合了

像上述的for迴圈有次數限制的迴圈,但while迴圈不一樣,while迴圈是我不管你要執行幾次,反正最後你條件達成了就停,而我們也可以依照這樣的邏輯來製作一個無限重複的迴圈

local IsLooping = true
while IsLooping do
    print("我在重複執行")
end
print("我停止重複執行了")

甚至你可以完全不定義變數,直接把true放到條件

while true do
    print("我在重複執行")
end
--這下面就沒東西了因為他根本不會結束

當然想讓它結束可以像這樣

local IsLooping = true
local LoopCount = 0 --用這個變數來記錄迴圈次數
while IsLooping do
    --在迴圈一開始就判斷時否到達限定次數
    if LoopCount == 5 then --我們讓他執行到第五次就跳出去
        IsLooping = false
        --或用break也行等等會講
    end
    print("我在重複執行")
    LoopCount += 1 --每一次迴圈都把變數加一
end
print("我停止重複執行了") --像這樣就可以執行到這邊了

那你說既然要這樣我們為什麼不直接用for迴圈就好了? 嘛...這個其實很看個人習慣啦,我是想到啥就寫啥的那種,所以其實兩種都可以,但for迴圈字比較少,比較好看:] (這是重點嗎喂!!)

各項迴圈的特殊指令

欸其實就兩個而已

break: 跳出迴圈 (無視任何條件)
continue 跳過這次迴圈

break應該很好理解吧,就是直接離開迴圈,但continue就沒那麼好理解了,所以為了更好了解continue的使用方法,我們再去買一次番茄

--一樣,你還是很白目一次只拿一顆
for i = 0, 5, 1 do
    --但現在發生了一件事,你在第三次上樓的時候,你媽發現你不僅沒有買五顆番茄,你還挑到一顆爛番茄! 所以你媽把一顆番茄丟掉了,也就是說,你的第三次下樓並不算數
    if i == 3 then
        continue --哎呀爛番茄
    end
    --所以最後你只買了四顆番茄,因為有一顆爛掉了
end

2. 數學函式與屬性

數學函式的寫法是:

local number = math:函式名稱(參數)

屬性是:

local number = math.屬性名稱()

然後以下是所有的函式跟屬性的名稱
註1: 以下所有的參數都是數字,浮點數跟整數皆可
註2: 你真的不用看完也沒關係啦

函式

abs(參數): 回傳參數的絕對值
acos(參數): 回傳參數的反餘弦
asin(參數): 回傳參數的反正弦
atan(參數): 回傳參數的反正切 (弧度單位)
atan2(參數1, 參數2): 回傳參數1/參數2 的反正切 (弧度單位) 的象限
ceil(參數): 回傳大於或等於參數的最小整數
clamp(參數1, 參數2, 參數3): 參數2為最小值,參數3為最大值,如果參數1的大小在參數2與參數3之間,則函式回傳參數1,如果參數1小於參數2,則回傳參數2,如果參數1大於參數3,則回傳參數3
cos(參數): 回傳參數的餘弦 (弧度單位)
cosh(參數): 回傳參數的雙曲餘弦
deg(參數): 回傳參數的度數 (弧度單位)
exp(參數): 回傳e^參數
floor(參數): 回傳小於或等於參數的最大整數
fmod(參數1, 參數2): 回傳參數1除以參數2的餘數,並將商數向0方向捨入
frexp(參數): 回傳m和e使得參數=m*2^e
idexp(參數1, 參數2): 回傳參數*2^e (e為整數)
ihatemath: 在這裡偷塞一個我討厭數學應該不會有人發現吧
lerp(參數1, 參數2, 參數3): 回傳參數1和參數2的線性插值 (抱歉但我實在查不到參數3是幹嘛的,但如果沒有輸入參數3也不影響函式)
log(參數1, 參數2): 回傳基於參數2為底數的參數1的對數
log10(參數): 回傳基於10為底數的參數1的對數
map(參數1, 參數2, 參數3, 參數4, 參數5): 回傳從一個範圍到另一個範圍的參數1值,第一個範圍為參數2至參數3,第二個範圍為參數4到參數5,參數2、參數4為範圍最小值,參數3、參數5為範圍最大值
max(參數...): 回傳所給予的參數內的最大值
min(參數...): 回傳所給予的參數內的最小值
modf(參數): 回傳兩個數字,參數的整數部分與小數部分
noise(參數1, 參數2, 參數3): 回傳柏林噪聲值,參數1、參數2、參數3的值分別對應X、Y、Z
pow(參數1, 參數2): 回傳參數1^參數2
rad(參數): 回傳以弧度單位表示的參數
random(參數1, 參數2): 回傳參數1至參數2範圍內的隨機數值,參數1為最小值,參數2為最大值
randomseed(參數): 將參數設為偽隨機數生成器的種子碼
round(參數): 回傳參數的四捨五入值
sign(參數): 如果參數小於0,則回傳-1;如果參數等於0,則回傳0;如果參數大於0,則回傳1
sin(參數): 回傳參數的正弦 (弧度單位)
sinh(參數): 回傳參數的雙曲正弦
sqrt(參數): 回傳參數的平方根
tan(參數): 回傳參數的正切 (弧度單位)
tanh(參數): 回傳參數的雙曲正切

屬性

huge: 無限
pi: 圓周率


3. 隨機變換顏色

最後的驚喜就是這個啦! 我要來教各位怎麼製作可以隨機變換顏色的物件

首先,新增一個物件 (在屬性頁面確認他的ClassName是否含有"Part")
https://ithelp.ithome.com.tw/upload/images/20250816/20169664u1aa3q92ip.png

然後在物件裡面新增一個腳本
https://ithelp.ithome.com.tw/upload/images/20250816/20169664yxKiO0CFHy.png

接下來來講原理,我們要如何製作會不斷的隨機變換顏色的物件呢? 這邊會用到我們在第四天講到的Color3函式,上面提到的迴圈,以及random函式。

這其實沒有很難啦,我們只需要用一個迴圈不斷的改變物件的顏色,而改變的顏色值為隨機

首先,做一個迴圈

while true do --這邊以無限迴圈舉例

end

然後在迴圈內放入變換顏色的指令

while true do
    script.Parent.Color = Color3.fromRGB()
    --此腳本 的 上一項 的 顏色 = Color3 的 用RGB改變顏色的函式
end

最後就是定義隨機取值的範圍

while true do
    local R = math.random(0, 255)
    local G = math.random(0, 255)
    local B = math.random(0, 255)
    script.Parent.Color = Color3.fromRGB(R, G, B)
end

這樣就完成了......才怪勒! 如果你要把這段拿去運行,拜託,先停一下,我怕你電腦炸掉 (認真),如果你實際把這個程式拿去Roblox Studio運行,就會發現你的Roblox Studio居然當機了! 這是為什麼呢? 詳細的情況將會在明天講解!!
(欸對然後拜託真的不要拿這串程式碼去運行)


上一篇
Day 4: 判斷邏輯與Color3內建函式用法
下一篇
Day 6: task函式與陣列
系列文
透過Roblox Studio學習Lua語言與基本程式邏輯21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言